Subject: Moving Bitplanes
From: "neil o'rourke" <[email-masked]>
To: [email-masked]
Date: Thu, 18 Aug 1994 08:16:42 +1000 (EST)

> > > 
 > > >   How can I move an individual bitplane in a bitmap??
 > > > 
 > 
 > > What do you mean exactly, "move an individual bitplane in a bit map"?
 > 
 > > You can simulate this effect by having a large off-screen bitmap, and
 > > copy over (or blit over) the section needed into the specified bitmap.
 > 
 > > If this is what you want, I've written some code to allow you use the
 > > blitter for this purpose.
 > 
 > What I would like, is to be able to draw into a specific bitplane
 > (using BitPlanesBitMap), and then scrolling this individual
 > bitplane around on top of the existing bitmap.
 > 
 > I would greatly appreciate looking at your code, to see if that
 > does the trick!  Thanks.
 
 I don't know if this is really what you want, but it might give you
 ideas.  This code uses the blitter directly to move data around a
 bitplane, and could simulate the effect you are after.
 
 This code runs under Intuition, but I didn't bother protecting myself
 with a call to OwnBlitter() and DisownBlitter().  The routines adapt
 themselves to whatever strange bitmaps you care to toss at it, and even
 works on my 4000/040 here at work.
 
 Regards,
 
 Neil
 
 -------------------------------------------------------------------------
NEWTYPE.CBMParams
;This newtype is the sole parameter to the CopyBM2 statement
  SBM.w     ;Source BitMap number
  DBM.w     ;Destination BitMap number (can be the same as Source)

  X1.w      ;\
  Y1.w      ; | Rectangle to cut
  W.w       ; | from source
  H.w       ;/

  X2.w      ;\ Destination for
  Y2.w      ;/ the Blit

  SrcBP.w   ;What bitplane to get image from.
  DestBP.w  ;This parameter tell the routine what bitplane to sent
            ;the src image to.  Ignored if -1.

End NEWTYPE

NEWTYPE.bitmap
  _ebwidth.w  ;even byte width of a bitmap
  _height.w   ;pixel height of bitmap
  _depth.w    ;depth, in bitplanes, of bitmap
  _pad.b[2]
  _data.l[8]  ;Max of 8 pointers to bitplanes
  _pad2.b[22]
  _isreal.w   ;=0: no bitmap present
              ;<0: bitmap present
              ;>0: bitmap present, but not ours
End NEWTYPE

#custom=$dff000       ;address of chip registers ("the metal")

#BLTCON0=#custom+$40  ;Blitter control register 0
#BLTCON1=#custom+$42  ;   "       "       "     1
#BLTAFWM=#custom+$44  ;Blitter first word mask for source A
#BLTALWM=#custom+$46  ;   "    last   "    "    "    "    "
#BLTCPTH=#custom+$48  ;Blitter pointer to source C (high 3 bits)
#BLTCPTL=#custom+$4a  ;   "       "    "    "    " (low 15 bits)
#BLTBPTH=#custom+$4c  ;Blitter pointer to source B (high 3 bits)
#BLTBPTL=#custom+$4e  ;   "       "    "    "    " (low 15 bits)
#BLTAPTH=#custom+$50  ;Blitter pointer to source A (high 3 bits)
#BLTAPTL=#custom+$52  ;   "       "    "    "    " (low 15 bits)
#BLTDPTH=#custom+$54  ;Blitter pointer to destination D (high 3 bits)
#BLTDPTL=#custom+$56  ;   "       "    "       "      " (low 15 bits)
#BLTSIZE=#custom+$58  ;Blitter start and size (window width,height)
#BLTCON0L=#custom+$5a ;Blitter control 0, lower 8 bits (minterms)
#BLTSIZV=#custom+$5c  ;Bliter V size (for 15 bit vertical size)
#BLTSIZH=#custom+$5e  ;Blitter H size and start (for 11 bit H size)
#BLTCMOD=#custom+$60  ;Blitter modulo for source C
#BLTBMOD=#custom+$62  ;Blitter modulo for source B
#BLTAMOD=#custom+$64  ;Blitter modulo for source A
#BLTDMOD=#custom+$66  ;Blitter modulo for destination D
#BLTCDAT=#custom+$70  ;Blitter source C data register
#BLTBDAT=#custom+$72  ;Blitter source B data register
#BLTADAT=#custom+$74  ;Blitter source A data register

#DMACONR=#custom+$02  ;DMA control register (read only)

#DMAB_BLTDONE=14

Macro WaitBlit
;This little macro busy-waits until the blitter is free
BTST.b #DMAB_BLTDONE-8,DMACONR
waitblit2: BTST.b #DMAB_BLTDONE-8,DMACONR:BNE waitblit2
End Macro

Statement CopyBM2{*BMP.CBMParams}
;This statement copys a rectangular section from SBM to DBM using
;the Blitter.

  DEFTYPE.bitmap *src,*dest

;get pointers to the bitmaps
  *src=Addr BitMap(*BMP\SBM)
  *dest=Addr BitMap(*BMP\DBM)

;Extract the data that we want
  SrcX.w=*BMP\X1/8      ;Result in bytes
  SrcY.w=*BMP\Y1        ;Result in scanlines
  SizeX.w=*BMP\W/8      ;Result in bytes
  SizeY.w=*BMP\H        ;Result in scanlines
  DestX.w=*BMP\X2/8     ;Result in bytes
  DestY.w=*BMP\Y2       ;Result in scanlines
  DDpth.w=*src\_depth   ;could use Depth(*BMP\SBM)

  ImageSPointer.w=(*src\_ebwidth*SrcY)+SrcX     ;This becomes our BLTAPTH
  ImageSModulo.w =*src\_ebwidth-SizeX           ;This becomes our BLTAMOD

  ImageDPointer.w=(*dest\_ebwidth*DestY)+DestX  ;This becomes our BLTDPTH
  ImageDModulo.w =*dest\_ebwidth-SizeX          ;This becomes our BLTDMOD

  BlitSize.w=(SizeY*64)+(SizeX/2)               ;This is the size of the blit

  If *BMP\DestBP=-1
    For PlaneCount.w=0 To DDpth-1
      !WaitBlit    ;Make sure the blitter isn't busy
      Poke.w #BLTCON0,%0000100111110000 ;Enable A and D channels, MinTerm =$f0
      Poke.w #BLTCON1,%0000000000000000
      Poke.w #BLTAMOD,ImageSModulo
      Poke.w #BLTDMOD,ImageDModulo
      Poke.w #BLTAFWM,$ffff
      Poke.w #BLTALWM,$ffff
      Poke.l #BLTAPTH,*src\_data[PlaneCount]+ImageSPointer
      Poke.l #BLTDPTH,*dest\_data[PlaneCount-1]+ImageDPointer
      Poke.w #BLTSIZE,BlitSize  ;This starts the blit
    Next PlaneCount
  Else
    Poke.w #BLTCON0,%0000100111110000 ;Enable A and D channels, MinTerm =$f0
    Poke.w #BLTCON1,%0000000000000000
    Poke.w #BLTAMOD,ImageSModulo
    Poke.w #BLTDMOD,ImageDModulo
    Poke.w #BLTAFWM,$ffff
    Poke.w #BLTALWM,$ffff
    Poke.l #BLTAPTH,*src\_data[*BMP\SrcBP]+ImageSPointer
    Poke.l #BLTDPTH,*dest\_data[*BMP\DestBP]+ImageDPointer
    Poke.w #BLTSIZE,BlitSize  ;This starts the blit
  End If
End Statement

;Now test the routine to demonstrate.

Screen 0,0,0,320,256,6,$80,"",2,1
ScreensBitMap 0,0
BitMapOutput 0
For x.w=0 To 31
  Boxf x*5,x*4,320-(x*5),256-(x*4),x
Next

DEFTYPE.CBMParams Txt,Erase

BitMap 1,320,256,1
BitMapOutput 1:Locate 0,0:Print "HALF-BRIGHT TEXT"
Txt\SBM=1
Txt\DBM=0
Txt\X1=0,0
Txt\W=16*8,8
Txt\X2=16,16
Txt\SrcBP=0
Txt\DestBP=5
Erase\SBM=1
Erase\DBM=0
Erase\X1=0,9
Erase\W=16*8,8
Erase\X2=16,16
Erase\SrcBP=0
Erase\DestBP=5

OldX.w=0:OldY.w=0

For x.w=0 To (320-(16*8)) Step 8
  For y.w=0 To 248
    If (x MOD 16)=0 Then cy=y Else cy=248-y
    Txt\X2=x,cy
    Erase\X2=OldX,OldY
    OldX=x:OldY=cy
    VWait:CopyBM2{&Erase}:CopyBM2{&Txt}:VWait
  Next y
Next x
End

------------------------------------------------------------------------
 
[email-masked]